package com.smart.carey.util;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.StringRedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SessionCallback;

import javax.servlet.http.HttpServletRequest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * session 操作工具类
 *
 * @author carey
 */

public class RedisManager {

    @Autowired
    private RedisTemplate redisTemplate;



     public List<String> batchQueryByKeys(List<String> keys, Boolean useParallel){

         List<String> list = this.redisTemplate.executePipelined((RedisCallback<String>) connection -> {
             RedisConnection conn = connection;
             for (String key : keys) {
                 conn.hGet(key.getBytes(),ConstantClassField.PUSH_ID.getBytes());
             }
             return null;
         });


        if(null == list || list.size() == 0 ){return null;}
        return  list;

    }


    /**
     * 获取当前request session存储的数据
     *
     * @param request
     * @return
     */
    public <T> T getCacheUser(Class<T> t, HttpServletRequest request) {
        String appToken= request.getHeader("appToken");
        appToken= AESUtil.decrypt(appToken, ConstantClassField.AESKEY);
        appToken = appToken.substring(0,appToken.indexOf("&&"));
        return (T) redisTemplate.opsForHash().get(appToken,ConstantClassField.USERMODEL);
    }

    /**
     * 获取当前request session存储的数据
     *
     * @param key
     * @return
     */
    public <T> T  getCacheUser(Class<T> t ,String key) {
        return  (T) redisTemplate.opsForHash().get(key,ConstantClassField.USERMODEL);
    }




    /**
     * 获取获取当前用户设备编号
     *
     * @param key
     * @return
     */
    public Object getUserDevicePin(String key) {
        return redisTemplate.opsForHash().get(key,ConstantClassField.DEVICEPIN);
    }

    /**
     * 获取获取当前用户设备编号
     *
     * @param key
     * @return
     */
    public Object getUserPushId(String key) {
        return redisTemplate.opsForHash().get(key,ConstantClassField.PUSH_ID);
    }

    /**
     * 获取获取当前用户设备编号
     *
     * @param key
     * @return
     */
    public void setUserPushId(String key,String val) {
         redisTemplate.opsForHash().put(key,ConstantClassField.PUSH_ID,val);
    }



    public List<Map<String, Object>> getUserToken(String userToken) {
        return (List<Map<String, Object>>) redisTemplate.opsForHash().get(userToken, ConstantClassField.USERTOEKN);

    }

    /**
     * 用户token 创建
     *
     * @param userModel
     * @param <T>
     * @return
     */
    public <T> String createToken(T userModel, String key, String devicePin,String pushId) {
        MD5Util md5Util = new MD5Util();
         String userToken = null;
        try {
            userToken = md5Util.Md5(key);
            List<Map<String, Object>> mapList = getUserToken(userToken);
            if (null != mapList && !mapList.isEmpty()) {
                redisTemplate.opsForHash().delete(userToken);
            }
            Map<String, Object> objectMap = new HashMap<>();
            objectMap.put(ConstantClassField.USERMODEL, userModel);
            objectMap.put(ConstantClassField.DEVICEPIN, devicePin);
            objectMap.put(ConstantClassField.PUSH_ID, pushId);
            redisTemplate.opsForHash().putAll(userToken, objectMap);
            //token有效期七天
            redisTemplate.expire(userToken, 7, TimeUnit.DAYS);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } finally {
            //加密存储token,混淆token
            try {
                userToken = userToken + "&&" + System.currentTimeMillis();
                System.out.println(userToken);
                userToken = AESUtil.encrypt(userToken,ConstantClassField.AESKEY);
                System.out.println(userToken);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return userToken;
        }
    }


}
